嗨!各位朋友大家好,打給後,歹嘎吼,胎尬喉,我是阿圓,一樣有請今天的one piece:
(我也想拿可樂當燃料,還不會轉換成我的熱量!!!)
鐵人賽已經邁入第十天,我的挑戰也已經過了三分之一了,但我居然 一行code都沒有放上來!!! 這真的太母湯了!趕快來補救一下!(其實是覺得放上自己寫的程式碼太羞恥才拖到今天QQ)
貼心提醒: 由於今天會放上我的部落格的程式碼,字數有點過長(爆炸長!),問題就讓我放到明天來寫吧(所以明天會有兩個問題!)
有登入、登出的動作,但不會有註冊的動作,畢竟部落格只有我一個人是管理者,打算直接用後台寫進去:
(感覺有點怪怪der,若有問題之後再來改XD")
# /routes.rb
Rails.application.routes.draw do
# 這邊為了測試,放了一個index給他,之後想要改成文章的首頁
root 'admins#index'
# 我不想要有預設的路徑,直接用最簡單的方式寫給他
get 'admins/sign_in', to: 'admins#sign_in'
post 'admins/sign_in', to: 'admins#login'
delete 'admins/sign_out', to: 'admins#sign_out'
end
<!-- admins/views/index.html.erb -->
<h1>臨時首頁</h1>
<%= link_to '登入', admins_sign_in_path%>
<%= link_to '登出', admins_sign_out_path, method: "delete"%>
<!-- admins/views/sign_in.html.erb -->
<h1>管理者登入</h1>
<%= form_for(@admin, url: admins_sign_in_path) do |f| %>
<div class="fields">
<%= f.label :account %>
<%= f.text_field :account, placeholder:'請輸入帳號' %>
</div>
<div class="fields">
<%= f.label :password, placeholder:'請輸入密碼' %>
<%= f.password_field :password %>
</div>
<%= f.submit "登入"%>
<% end %>
這裡是用form_for
來建立登入的表單,畫面如下:
$ rails g controller admins
接著定義action,將routes上的action寫上去:
def sign_in
#do something
end
def login
#do something
end
def sign_out
#do something
end
先建立model$ rails g model Admin account password:password
Admin有兩個欄位,account 跟 password
# /admin.rb
class Admin < ApplicationRecord
# account password 必填
validates :account, presence: true, uniqueness: true
validates :password, presence: true
# 在create之前,將密碼加密
before_create :encrypt_password
end
自定義自己的密碼加密方式,要在Admin這邊的一個物件create之前將密碼加密,在下面 private 的寫下:
private
def encrypt_password
self.password = popper(password)
end
def popper(string)
string = 'cu' + string + 'te'
Digest::SHA1.hexdigest(string)
end
所謂 popper
,就是在密碼前後加些綴字,讓密碼更難破解(不過我都放上來了XD,就相當於無效了哈哈)。
# /admins_controller.rb
# 在Admin的類別中,新增一個@admin的實體變數
def sign_in
@admin = Admin.new
end
接著來定義按下登入按鈕後,要進行的事情:
# /admins_controller.rb
def login
admin = Admin.login(admin_params)
# 確認資料庫裡是否有使用相同account和password的管理員
if admin
sign_in_admin(admin) #定義在下方,發session
redirect_to root_path, notice: '成功登入!'
# 轉址回根目錄
else
redirect_to sign_in_admins_path, notice: '請輸入正確帳號密碼'
# 轉址回登入頁面
end
end
其中,第2行的 login
是為了要去比對資料庫裡是否有相同帳號密碼的使用者,所以將方法定義在 admin 的 model 裡面(所有的 admin 都有 login 的方法),如下:
# /admin.rb
def self.login(options)
if options[:account] && options[:password]
find_by(account: options[:account],
password: Digest::SHA1.hexdigest('cu' + options[:password] + 'te'))
end
end
上面做了什麼呢?有請圖解!
搞定了model的login方法,接著來繼續回來controller,在下面加上:
# /admins_controller.rb
private
def sign_in_admin(a)
session[:admin_token] = SecureRandom.uuid
# 這裡使用了SecureRandom的方法,他是一個在rails 裡寫好的module,所以要去最上面加上 "require 'securerandom'"
end
def admin_params
params.require(:admin).permit(:account, :password)
end
簡單解釋一下 admin_params
做的事情,是將是將登入頁面打過來的資訊,清洗後再傳給 server,若沒有 permit
,在 create
資料的時候,就會得到下列畫面:
這就是所謂的 Strong parameter
問題,等待明天揭曉,若想先睹為快,請參閱為你自己學 Ruby on Rails 。
但因為login
這個 action
沒有建立新的資料,所以就算沒有寫,網頁也不會噴錯(我把方法改成 create,
才得到這個畫面!)
直接把session清掉!
# /admins_controller.rb
def sign_out
sign_out_admin
redirect_to root_path, notice: '會員登出成功'
end
private
def sign_out_admin
session[:admin_token] = nil
end
目前這就是我實作管理員系統的流程,感謝各位看到這邊,若有任何建議,我非常需要各位的指教
!
謝謝大家!我們明天見!